﻿using System;
using System.Diagnostics;
using System.IO;

using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.WowAddonStudio.Lua.LanguageService.Intellisense.Providers;

namespace Microsoft.WowAddonStudio.Lua.LanguageService.Support
{
    [DebuggerDisplay("Name = {Name}")]
    public class HierarchyManager
    {
        private readonly IVsHierarchy hierarchy;
        private readonly IServiceProvider serviceProvider;

        /// <summary>
        /// Initializes a new instance of the <see cref="HierarchyManager"/> class.
        /// </summary>
        /// <param name="serviceProvider">The service provider.</param>
        /// <param name="hierarchy">The Visual Studio hierarchy.</param>
        public HierarchyManager(IServiceProvider serviceProvider, IVsHierarchy hierarchy)
        {
            if (serviceProvider == null) 
                throw new ArgumentNullException("serviceProvider");
            if (hierarchy == null)
                throw new ArgumentNullException("hierarchy");

            this.serviceProvider = serviceProvider;
            this.hierarchy = hierarchy;
            this.Initialize();
        }

        private void Initialize()
        {
            string rootPath;
            if (hierarchy.GetCanonicalName(VSConstants.VSITEMID_ROOT, out rootPath) != VSConstants.S_OK)
                throw new ArgumentException("Could not retrieve canonical name of root item.", "hierarchy");

            this.Name = Path.GetFileNameWithoutExtension(rootPath);
        }

        /// <summary>
        /// Gets the name of the project hierarchy.
        /// </summary>
        public string Name { get; private set; }

        /// <summary>
        /// Creates a stream provider for the hierarchy.
        /// </summary>
        /// <returns></returns>
        public HierarchyStreamProvider CreateStreamProvider()
        {
            return new HierarchyStreamProvider(serviceProvider, hierarchy);
        }

        private bool TryGetProperty<T>(uint itemid, int propid, out T value)
        {
            value = default(T);

            object var;
            if (hierarchy.GetProperty(itemid, propid, out var) != VSConstants.S_OK)
                return false;
            if (!(var is T))
                return false;

            value = (T)var;
            return true;
        }
    }
}
